let _Vue = null

export default class VueRouter {
  static install (Vue) {
    // 判断当前插件是否已经被安装
    if (VueRouter.install.installed) {
      return
    }
    VueRouter.install.installed = true
    // 把Vue构造函数记录到全局
    _Vue = Vue
    // 把创建Vue实例传入router对象注入到Vue实例上
    // 混入
    _Vue.mixin({
      beforeCreate () {
        if (this.$options.router) {
          _Vue.prototype.$router = this.$options.router
          this.$options.router.init()
        }
      }
    })
  }

  constructor (options) {
    this.options = options
    this.mode = options.mode || 'hash'
    this.routeMap = {}
    this.data = _Vue.observable({
      current: this.mode === 'hash' ? this.hashcurrent() : this.historycurrent()
    })
  }

  init () {
    this.createRouteMap()
    this.initComponents(_Vue)
    this.initEvent()
    this.reloadUrl()
  }

  reloadUrl () {
    // 判断hash初始页面
    if (this.mode === 'hash' && window.location.href.indexOf('#') < 0) {
      history.pushState({}, '', '/#/')
      this.data.current = '/'
    }
  }

  createRouteMap () {
    this.options.routes.forEach(route => {
      this.routeMap[route.path] = route.component
    })
  }

  initComponents (Vue) {
    const self = this
    Vue.component('router-link', {
      props: {
        to: String
      },
      render (h) {
        return h('a', {
          attrs: {
            href: self.mode === 'hash' ? '#' + this.to : this.to
          },
          on: {
            click: self.mode === 'hash' ? this.clickHashHandler : this.clickHandler
          }
        }, [this.$slots.default])
      },
      methods: {
        clickHandler (e) {
          history.pushState({}, '', this.to)
          this.$router.data.current = this.to
          e.preventDefault()
        },
        clickHashHandler () {
          this.$router.data.current = this.to
        }
      }
    })

    Vue.component('router-view', {
      render (h) {
        const component = self.routeMap[self.data.current]
        return h(component)
      }
    })
  }

  initEvent () {
    const m = this.mode === 'history' ? 'popstate' : 'hashchange'
    window.addEventListener(m, () => {
      this.data.current = this.mode === 'history' ? this.historycurrent() : this.hashcurrent()
    })
  }
  hashcurrent () {
    const href = window.location.href
    const index = href.indexOf('#')
    return index < 0 ? '/#/' : href.slice(index + 1)
  }

  historycurrent () {
    return window.location.pathname
  }

  // vue3源码方法
  // readonly currentRoute: Ref<RouteLocationNormalizedLoaded>;
  // readonly options: RouterOptions;
  // //  添加传入父级名称路由的子路由
  // addRoute(parentName: RouteRecordName, route: RouteRecordRaw): () => void;
  // //  添加路由
  // addRoute(route: RouteRecordRaw): () => void;
  // //  按名称删除路由
  // removeRoute(name: RouteRecordName): void;
  // //  检测是否存在传入名称的路由
  // hasRoute(name: RouteRecordName): boolean;
  // //  获取全部路由
  // getRoutes(): RouteRecord[];
  // //  配置路由设置
  // // 例如：@路径
  // resolve(to: RouteLocationRaw, currentLocation?: RouteLocationNormalizedLoaded): RouteLocation & {
  //     href: string;
  // };
  // //  跳转
  // push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>;
  // //  不保存历史记录跳转
  // // 替换当前历史记录
  // replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>;
  // //  在浏览器记录中后退一步
  // //  等同于router.go(-1)
  // back(): ReturnType<Router['go']>;
  // //  在浏览器记录中前进一步
  // //  等同于router.go(1)
  // forward(): ReturnType<Router['go']>;
  // //  历史记录前进后退
  // go(delta: number): void;
  // //  拦截器
  // beforeEach(guard: NavigationGuardWithThis<undefined>): () => void;
  // //  前置钩子
  // beforeResolve(guard: NavigationGuardWithThis<undefined>): () => void;
  // //  后置钩子
  // afterEach(guard: NavigationHookAfter): () => void;
  // isReady(): Promise<void>;
  // install(app: App): void;
}
